﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Cubicle.Core.DataContracts;
using Cubicle.Core.Interfaces;

namespace Cubicle.Core.Shared
{
    public class MemoryResolver : IResolver
    {
        #region Implementation of IResolver

        public bool AutoAssemblyResolveState { get; set; }

        public Assembly ResolveAssembly(string fullName)
        {
            var type = Type.GetType(fullName);
            return type == null 
                       ? null 
                       : type.Assembly;
        }

        public bool CanResolve(string fullName)
        {
            return Type.GetType(fullName) != null;
        }

        public IEnumerable<AssemblyData> ListAssemblies()
        {
            return AppDomain
                .CurrentDomain
                .GetAssemblies()
                .Select(x => new AssemblyData(x));
        }

        public IEnumerable<TypeData> ListTypes(string asmId)
        {
            return new List<TypeData>();
        }

        public IEnumerable<TypeData> FindAll<TInterface>()
        {
            return AppDomain.CurrentDomain
                .GetAssemblies()
                .SelectMany(x => x.GetTypes())
                .Where(x => x.GetInterfaces().Contains(typeof (TInterface)))
                .Select(x => new TypeData(x));
        }

        public IEnumerable<TypeData> FindAll(string interfaceName)
        {
            return AppDomain.CurrentDomain
                .GetAssemblies()
                .SelectMany(x => x.GetTypes())
                .Where(x => x.GetInterfaces().Select(i => i.FullName).Contains(interfaceName))
                .Select(x => new TypeData(x));
        }

        public IEnumerable<Type> FindTypes<TInterface>(IEnumerable<string> typeNames)
        {
            if (typeNames == null) return null;
            return AppDomain.CurrentDomain
                .GetAssemblies()
                .SelectMany(x => x.GetTypes())
                .Where(x => x.FullName != null)
                .Where(x => typeNames.Contains(x.FullName));
        }

        public IEnumerable<Type> FindTypes<TInterface>()
        {
            return AppDomain.CurrentDomain
                .GetAssemblies()
                .SelectMany(x => x.GetTypes())
                .Where(x => x.GetInterfaces().Select(i => i.FullName).Contains(typeof (TInterface).FullName));
        }

        #endregion
    }
}